package com.example.rbacmanage.aspect;

import com.alibaba.druid.util.StringUtils;
import com.example.rbacmanage.annotation.PermissionRange;
import com.example.rbacmanage.base.BaseEntity;
import com.example.rbacmanage.entity.system.Role;
import com.example.rbacmanage.vo.MyUserDetails;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 权限范围切面
 */
@Aspect
@Component
public class PermissionRangeAspect {
    //全部数据权限
    public static final String  ALL_DATA_PERMISSION="0";
    //自定义数据权限
    public static final String DEFINED_DATA_PERMISSION="1";
    //部门数据权限
    public static final String DEPT_DATA_PERMISSION="2";
    //部门及以下数据权限
    public static final String DEPT_AND_END_DATA_PERMISSION="3";
    //仅本人数据权限
    public static final String ONLY_SELF_DATA_PERMISSION="4";
    //店铺数据权限
    public static final String SHOP_DATA_PERMISSION="5";
    //权限范围过滤关键字
    public static final String PERMISSION_RANGE="permissionRange";

    @Before("@annotation(permissionRange)")
    public void doBefore(JoinPoint point, PermissionRange permissionRange){
        Object params = point.getArgs()[0];
        if(!ObjectUtils.isEmpty(params) && params instanceof BaseEntity){
            BaseEntity baseEntity = (BaseEntity) params;
            baseEntity.getParams().put(PERMISSION_RANGE,"");
        }
        //获取当前用户
        MyUserDetails myUserDetails = (MyUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (!ObjectUtils.isEmpty(myUserDetails)){
            //如果是管理员，则不过滤数据
            if (!myUserDetails.getId().equals(1)){
                String permission = permissionRange.permission();
                StringBuilder stringBuilder = new StringBuilder();
                List<String> conditions = new ArrayList<>();
                for (Role role : myUserDetails.getRoles()){
                    //不是自定义权限，且条件已经有值，则继续循环
                    String permissionrangge = role.getPermissionRange();
                    if (!DEFINED_DATA_PERMISSION.equals(permissionrangge) && conditions.contains(permissionrangge)){
                        continue;
                    }
                    //角色下的权限码不包含此权限，继续循环
                    if (!StringUtils.isEmpty(permission) && !ObjectUtils.isEmpty(role.getPermissions())
                    && !role.getPermissions().contains(permission)){
                        continue;
                    }
                    //是全部数据权限，则中断循环
                    if (ALL_DATA_PERMISSION.equals(permissionrangge)){
                        stringBuilder = new StringBuilder();
                        conditions.add(permissionrangge);
                        break;
                    }else if (DEFINED_DATA_PERMISSION.equals(permissionrangge)){
                        //是自定义数据权限，则sql拼接注入相关条件
                        stringBuilder.append(String.format(" OR %s.id in (SELECT dept_id from t_role_dept WHERE role_id = %s ) ",
                                permissionRange.deptAlias(),role.getId()));
                    }else if (DEPT_DATA_PERMISSION.equals(permissionrangge)){
                        //部门数据权限，拼接部门条件
                        stringBuilder.append(String.format(" OR %s.id = %s ",permissionRange.deptAlias(),myUserDetails.getUser().getDeptId()));
                    }else if (DEPT_AND_END_DATA_PERMISSION.equals(permissionrangge)){
                        //部门及以下数据权限
                        stringBuilder.append(String.format(" OR %s.id IN ( SELECT id  FROM t_dept WHERE id = %s or find_in_set( %s, ancestors ) ) ",
                                permissionRange.deptAlias(),myUserDetails.getUser().getDeptId(),myUserDetails.getUser().getDeptId()));
                    }else if (ONLY_SELF_DATA_PERMISSION.equals(permissionrangge)){
                        //自定义数据权限
                        //用户别名不为空
                        if (!StringUtils.isEmpty(permissionRange.userAlias())){
                            stringBuilder.append(String.format(" OR %s.id=%s ",
                                    permissionRange.userAlias(),myUserDetails.getId()));
                        }else{
                            // 数据权限为仅本人且没有userAlias别名不查询任何数据
                            stringBuilder.append(String.format(" OR %s.id = 0 ", permissionRange.deptAlias()));
                        }
                    }else if (SHOP_DATA_PERMISSION.equals(permissionrangge)){
                        //店铺数据权限
                        stringBuilder.append(String.format(" OR %s.id = %s ",permissionRange.shopAlias(),myUserDetails.getUser().getShopId()));
                    }
                    conditions.add(permissionrangge);
                }
                // 多角色情况下，所有角色都不包含传递过来的权限字符，这个时候sqlString也会为空，所以要限制一下,不查询任何数据
                if (ObjectUtils.isEmpty(conditions))
                {
                    stringBuilder.append(String.format(" OR %s.id = 0 ",
                            permissionRange.deptAlias()));
                }

                if (!StringUtils.isEmpty(stringBuilder.toString())){
                    Object parames = point.getArgs()[0];
                    if (!ObjectUtils.isEmpty(parames) && parames instanceof BaseEntity){
                        BaseEntity baseEntity = (BaseEntity) parames;
                        baseEntity.getParams().put(PERMISSION_RANGE," AND ("+stringBuilder.substring(4)+")");
                    }
                }


            }
        }
    }
}
